#pragma once 
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include "log.hpp"

class tcpserver
{
  private:
    int port;
    int listen_sock;

    static tcpserver* ser;
    tcpserver(int _port):port(_port),listen_sock(-1)
    {}
    tcpserver(const tcpserver & s)
    {}
  public:
    static tcpserver* getinstance(int por)
    {
      static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;//定义静态的锁可以直接用宏来定义
      if(ser==nullptr)
      {
        pthread_mutex_lock(&lock);
          if(ser==nullptr)
          {
            ser=new tcpserver(por);
            ser->Isitserver();
          }
        pthread_mutex_unlock(&lock);
      }
      return ser;
    }
  public:
    ~tcpserver()
    {}
    void Isitserver()
    {
      Socket();
      Bind();
      Listen();
      LOG(INFO,"tcpserver isit 成功");
    }
    void Socket()
    {
      listen_sock=socket(AF_INET,SOCK_STREAM,0);
        if(listen_sock<0)
        {
          LOG(FATAL,"tcpserver socket 失败");
          exit(1);
        }
        int opt=1;
        setsockopt(listen_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
          LOG(INFO,"tcpserver socket 成功");
    }
    void Bind()
    {
      struct sockaddr_in local;
      memset(&local,0,sizeof(local));
      local.sin_family=AF_INET;
      local.sin_port=htons(port);
      local.sin_addr.s_addr=INADDR_ANY;

     if( bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0)
     {
          LOG(FATAL,"tcpserver bind 失败");
       exit(2);
     }
          LOG(INFO,"tcpserver bind 成功");
    }
    void Listen()
    {
      if(listen(listen_sock,5)<0)
      {
        LOG(FATAL,"tcpserver listen 失败");
        exit(3);
      }
      LOG(INFO,"tcpserver listen 成功");
    }
    int Sock()
    {
      return listen_sock;
    }
};

tcpserver* tcpserver::ser=nullptr;
